package org.abc.fund.controller.factorController;

import lombok.RequiredArgsConstructor;
import org.abc.fund.entity.factorEntity.DerivedFactor;
import org.abc.fund.entity.factorEntity.DerivedFactorData;
import org.abc.fund.entity.factorEntity.DerivedFactorDto;
import org.abc.fund.service.factorService.DerivedFactorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 衍生因子管理Controller
 */
@RestController
@CrossOrigin
@RequestMapping("/derived")
@RequiredArgsConstructor
public class DerivedFactorController {
    private static final Logger log = LoggerFactory.getLogger(DerivedFactorController.class);
    private final DerivedFactorService derivedFactorService;

    /**
     * 获取所有衍生因子（不分页）
     */
    @GetMapping("/dev/noPage")
    public ResponseEntity<?> getAllDerivedFactors(@RequestParam(required = false) Boolean enabled) {
        try {
            List<DerivedFactor> factors = derivedFactorService.getAllDerivedFactors(enabled);
            return ResponseEntity.ok(factors);
        } catch (Exception e) {
            log.error("获取衍生因子列表失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 获取所有衍生因子（不分页）
     */
    @GetMapping("/derived-factor/noPage")
    public ResponseEntity<List<DerivedFactor>> getAllDerivedFactors() {
        try {
            List<DerivedFactor> factors = derivedFactorService.getAllDerivedFactors(null);
            return ResponseEntity.ok(factors);
        } catch (Exception e) {
            log.error("获取衍生因子列表失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 创建衍生因子
     */
    @PostMapping("/dev/create")
    public ResponseEntity<?> create(@RequestBody DerivedFactorDto dto) {
        try {
            // 验证必填字段
            if (dto.getName() == null || dto.getName().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子名称不能为空"));
            }
            if (dto.getFactorCode() == null || dto.getFactorCode().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }
            if (dto.getOperator() == null || dto.getOperator().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "算子不能为空"));
            }
            if (dto.getInputFactors() == null || dto.getInputFactors().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "输入因子不能为空"));
            }
            if (dto.getParameters() == null || dto.getParameters().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "参数配置不能为空"));
            }

            DerivedFactor createdFactor = derivedFactorService.createDerivedFactor(
                    dto.getName(), dto.getFactorCode(), dto.getOperator(),
                    dto.getInputFactors(), dto.getParameters(), dto.getCalculationPeriod(),
                    dto.getLookbackPeriod(), dto.isEnabled(), dto.getDescription()
            );

            if (createdFactor != null) {
                return ResponseEntity.ok(createdFactor);
            } else {
                return ResponseEntity.badRequest().body(Map.of("error", "创建衍生因子失败"));
            }
        } catch (IllegalArgumentException e) {
            log.warn("创建衍生因子参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            log.error("创建衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 更新衍生因子
     */
    @PutMapping("/dev/update/{id}")
    public ResponseEntity<?> update(@RequestBody DerivedFactorDto dto) {
        try {
            if (dto.getName() == null || dto.getName().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子名称不能为空"));
            }
            if (dto.getFactorCode() == null || dto.getFactorCode().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }
            if (dto.getOperator() == null || dto.getOperator().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "算子不能为空"));
            }
            if (dto.getInputFactors() == null || dto.getInputFactors().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "输入因子不能为空"));
            }
            if (dto.getParameters() == null || dto.getParameters().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "参数配置不能为空"));
            }

            DerivedFactor updatedFactor = derivedFactorService.updateDerivedFactor(dto.getFactorCode(), dto);
            if (updatedFactor != null) {
                return ResponseEntity.ok(updatedFactor);
            } else {
                return ResponseEntity.badRequest().body(Map.of("error", "更新衍生因子失败"));
            }
        } catch (IllegalArgumentException e) {
            log.warn("更新衍生因子参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            log.error("更新衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 根据Code删除衍生因子
     */
    @DeleteMapping("/dev/delete/{factorCode}")
    public ResponseEntity<?> delete(@PathVariable String factorCode) {
        try {
            if (factorCode == null || factorCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }
            derivedFactorService.deleteDerivedFactorData(factorCode);
            return ResponseEntity.ok(Map.of("message", "删除成功"));
        } catch (IllegalArgumentException e) {
            log.warn("删除衍生因子参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            log.error("删除衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 根据ID查找衍生因子
     */
    @GetMapping("/dev/searchById/{id}")
    public ResponseEntity<?> findById(@PathVariable Long id) {
        try {
            Optional<DerivedFactor> factor = derivedFactorService.findById(id);
            return factor.map(ResponseEntity::ok)
                    .orElseGet(() -> ResponseEntity.notFound().build());
        } catch (Exception e) {
            log.error("查找衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 根据因子代码查找衍生因子
     */
    @GetMapping("/dev/searchByFactorCode/{factorCode}")
    public ResponseEntity<?> findByCode(@PathVariable String factorCode) {
        try {
            if (factorCode == null || factorCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }
            Optional<DerivedFactor> factor = derivedFactorService.findByFactorCode(factorCode);
            return factor.map(ResponseEntity::ok)
                    .orElseGet(() -> ResponseEntity.notFound().build());
        } catch (Exception e) {
            log.error("根据代码查找衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 分页查询衍生因子
     */
    @GetMapping("/derived-factor/page")
    public Page<DerivedFactor> page(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) Boolean enabled
    ) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "updateTime"));
        return derivedFactorService.findDerivedFactors(enabled, pageable);
    }

    /**
     * 多条件搜索衍生因子
     */
    @GetMapping("/dev/search")
    public ResponseEntity<?> search(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String code,
            @RequestParam(required = false) String operator,
            @RequestParam(required = false) Boolean enabled,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            Pageable pageable = PageRequest.of(page, size);
            Page<DerivedFactor> result = derivedFactorService.searchDerivedFactors(name, code, operator, enabled, pageable);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("搜索衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 模糊查询因子名称
     */
    @GetMapping("/dev/mhSearchByName")
    public ResponseEntity<?> searchByName(@RequestParam String name) {
        try {
            if (name == null || name.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "搜索名称不能为空"));
            }
            List<DerivedFactor> result = derivedFactorService.findByFactorNameContaining(name);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("按名称搜索衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 模糊查询因子代码
     */
    @GetMapping("/dev/mhSearchByCode")
    public ResponseEntity<?> searchByCode(@RequestParam String code) {
        try {
            if (code == null || code.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "搜索代码不能为空"));
            }
            List<DerivedFactor> result = derivedFactorService.findByFactorCodeContaining(code);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("按代码搜索衍生因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 启用/禁用衍生因子
     */
    @PatchMapping("/dev/{id}/status")
    public ResponseEntity<?> toggleStatus(@PathVariable Long id, @RequestParam Boolean enabled) {
        try {
            if (enabled == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "状态参数不能为空"));
            }
            DerivedFactor result = derivedFactorService.toggleDerivedFactorStatus(id, enabled);
            return ResponseEntity.ok(result);
        } catch (IllegalArgumentException e) {
            log.warn("切换衍生因子状态参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            log.error("切换衍生因子状态失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 计算单个衍生因子
     */
    @PostMapping("/dev/calculate/{derivedFactorType}/{fundCode}")
    public ResponseEntity<?> calculate(@PathVariable String derivedFactorType, @PathVariable String fundCode) {
        try {
            BigDecimal result = derivedFactorService.calculateDerivedFactorValue(derivedFactorType, fundCode);
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("factorValue", result);
            response.put("message", "计算成功");
            return ResponseEntity.ok(response);
        } catch (IllegalArgumentException e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "服务器内部错误");
            return ResponseEntity.status(500).body(response);
        }
    }

    /**
     * 验证衍生因子公式
     */
    @PostMapping("/dev/validate-formula")
    public ResponseEntity<?> validateFormula(@RequestBody Map<String, String> request) {
        try {
            String formula = request.get("formula");
            if (formula == null || formula.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "公式不能为空"));
            }

            // 这里应该调用公式验证服务
            boolean isValid = formula != null && !formula.trim().isEmpty();

            Map<String, Object> result = Map.of(
                    "valid", isValid,
                    "message", isValid ? "公式格式正确" : "公式格式错误"
            );

            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("验证衍生因子公式失败", e);
            Map<String, Object> result = Map.of(
                    "valid", false,
                    "message", "公式验证失败: " + e.getMessage()
            );
            return ResponseEntity.badRequest().body(result);
        }
    }

    /**
     * 检查衍生因子是否可计算
     */
    @GetMapping("/dev/check-calculable/{factorCode}")
    public ResponseEntity<?> checkCalculable(@PathVariable String factorCode) {
        try {
            if (factorCode == null || factorCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of(
                        "factorCode", factorCode,
                        "calculable", false,
                        "message", "因子代码不能为空"
                ));
            }

            // 检查因子是否存在
            Optional<DerivedFactor> derivedFactor = derivedFactorService.findByFactorCode(factorCode);
            if (derivedFactor.isEmpty()) {
                return ResponseEntity.ok(Map.of(
                        "factorCode", factorCode,
                        "calculable", false,
                        "message", "衍生因子不存在"
                ));
            }

            DerivedFactor factor = derivedFactor.get();

            // 检查是否启用
            if (!factor.getEnabled()) {
                return ResponseEntity.ok(Map.of(
                        "factorCode", factorCode,
                        "calculable", false,
                        "message", "衍生因子已禁用"
                ));
            }

            // 检查是否有计算组件
            boolean hasComponents = derivedFactorService.hasComponents(factorCode);
            if (!hasComponents) {
                return ResponseEntity.ok(Map.of(
                        "factorCode", factorCode,
                        "calculable", false,
                        "message", "衍生因子未配置计算公式"
                ));
            }

            return ResponseEntity.ok(Map.of(
                    "factorCode", factorCode,
                    "calculable", true,
                    "message", "衍生因子可以计算"
            ));

        } catch (Exception e) {
            log.error("检查衍生因子可计算性失败: 因子={}, 错误={}", factorCode, e.getMessage(), e);
            return ResponseEntity.internalServerError().body(Map.of(
                    "factorCode", factorCode,
                    "calculable", false,
                    "message", "检查失败: " + e.getMessage()
            ));
        }
    }

    /**
     * 保存衍生因子计算结果
     */
    @PostMapping("/dev/save-calculation-result")
    public ResponseEntity<?> saveCalculationResult(@RequestBody Map<String, Object> request) {
        try {
            String factorCode = (String) request.get("factorCode");
            String fundCode = (String) request.get("fundCode");
            Object factorValueObj = request.get("factorValue");

            if (factorCode == null || factorCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "因子代码不能为空"
                ));
            }

            if (fundCode == null || fundCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "基金代码不能为空"
                ));
            }

            if (factorValueObj == null) {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "因子值不能为空"
                ));
            }

            BigDecimal factorValue;
            if (factorValueObj instanceof Number) {
                factorValue = new BigDecimal(factorValueObj.toString());
            } else if (factorValueObj instanceof String) {
                factorValue = new BigDecimal((String) factorValueObj);
            } else {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "因子值格式错误"
                ));
            }

            log.info("保存衍生因子计算结果: 因子={}, 基金={}, 值={}", factorCode, fundCode, factorValue);

            // 调用服务保存计算结果
            derivedFactorService.saveCalculationResult(factorCode, fundCode, factorValue);

            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "计算结果保存成功",
                    "factorCode", factorCode,
                    "fundCode", fundCode,
                    "factorValue", factorValue
            ));

        } catch (NumberFormatException e) {
            log.warn("保存计算结果参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of(
                    "success", false,
                    "message", "因子值格式错误"
            ));
        } catch (Exception e) {
            log.error("保存衍生因子计算结果失败", e);
            return ResponseEntity.internalServerError().body(Map.of(
                    "success", false,
                    "message", "保存失败: " + e.getMessage()
            ));
        }
    }

    /**
     * 根据因子代码和基金代码查询最新的衍生因子计算结果
     */
    @GetMapping("/derived-factor/latest-result")
    public ResponseEntity<?> getLatestResult(@RequestParam String type, @RequestParam String fundCode) {
        try {
            Optional<DerivedFactorData> result = derivedFactorService.getLatestCalculationResult(type, fundCode);
            if (result.isPresent()) {
                return ResponseEntity.ok(result.get());
            } else {
                return ResponseEntity.ok().body(null);
            }
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * 根据ID删除衍生因子
     */
    @DeleteMapping("/dev/deleteById/{id}")
    public ResponseEntity<?> deleteDerivedFactor(@PathVariable Long id) {
        boolean deleted = derivedFactorService.deleteDerivedFactorById(id);
        if (deleted) {
            return ResponseEntity.ok(Map.of("success", true, "message", "删除成功"));
        } else {
            return ResponseEntity.status(404).body(Map.of("success", false, "message", "未找到该衍生因子"));
        }
    }
}